#pragma ident "$Id: Edge.hpp $"

/**
 * @file Edge.hpp
 * Class to define and handle the edge of observation graph.
 */

#ifndef EDGE_HPP
#define EDGE_HPP

//============================================================================
//
//  2019/09/20
//  change the structure of this class, ambiguity is a memeber of this class
//
//  2020/01/20
//  replace class 'Ambiguity' with 'Variable'
// 
//  Shoujian Zhang - School of Geodesy and Geomatics, Wuhan University, 2011
//
//============================================================================

#include <set>
#include <map>
#include <list>
#include <queue>
#include <vector>

#include "Variable.hpp"
#include "DataStructures.hpp"
#include "constants.hpp"


namespace gpstk
{

    /** @addtogroup DataStructures */
    //@{


    /// Class to define and handle the edge of observation graph.
   class Edge: public Variable 
   {
   public:

        /// Default constructor for Edge
        Edge() {}


        /** Common constructor for Edge.
         *
         * @param source     Source this Edge is related to.
         * @param sat        Satellite this Edge is related to.
         * @param weight     Variable representing the independent term.
         */
        Edge( const Variable& variable,
              const double variance)
            : Variable(variable),
              edgeVar(variance)
        {}


        /// Assignment operator.
        Edge& operator=(const Edge& right)
            throw();


        /// Get apriori variance this variable is assigned to (if any).
        double getVar() const
        { return edgeVar; }


        /** Set apriori variance this variable is assigned to.
         *
         */
        Edge& setVar(const double& variance)
        {
            edgeVar = variance;
            return (*this);
        }


        /// This ordering is required to be able
        /// to use Edge in std::map or std::set.
        virtual bool operator<(const Edge& right) const;


        /// Destructor
        virtual ~Edge() {}


    private:

        /// Apriori variance of this edge .
        double edgeVar;


    }; // End of class 'Edge'


      // Stream output for Vertex
   inline std::ostream& operator<<( std::ostream& s,
                             const Edge& e )
   {
       Edge e1 = e;
       Variable* pA = dynamic_cast<Variable*> (&e1);
       s << (*pA) << " " 
         << e.getVar() ;

       return s;

   }  // End of 'operator<<'


    /// Handy type definition
    typedef std::set<Edge> EdgeSet;

    /// Output
    namespace StringUtils
    {
        inline std::string asString(const Edge& v)
        {
            std::ostringstream oss;

            Edge v1 = v;
            Variable* pA = dynamic_cast<Variable*> (&v1);

            oss << asString(*pA) << " "
                << v.getVar() << " " ;

            return oss.str();
        }
    }

    //@}

}  // End of namespace gpstk

#endif   // EDGE_HPP
